using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using Komires.MataliPhysics;

namespace MataliPhysicsDemo
{
    public sealed class HelicoptersScene : IDemoScene
    {
        Demo demo;
        PhysicsScene scene;
        string name;
        string instanceIndexName;
        string info;

        public PhysicsScene PhysicsScene { get { return scene; } }
        public string SceneName { get { return name; } }
        public string SceneInfo { get { return info; } }

        // Declare objects in the scene
        Sky skyInstance1;
        Quad quadInstance1;
        Cursor cursorInstance;
        Shot shotInstance;
        Box1 boxInstance;
        Test testInstance;
        Wall wall1Instance;
        Wall wall1Instance2;
        Wall wall1Instance3;
        DefaultShapes defaultShapesInstance;
        UserShapes userShapeInstance;
       // TestObject testObjectInstance;

        Camera2 camera2Instance1;

        // Declare controllers in the scene
        SkyDraw1 skyDraw1Instance1;
        CursorDraw1 cursorDraw1Instance;

        Camera2Animation1 camera2Animation1Instance1;
        Camera2Draw1 camera2Draw1Instance1;

        public HelicoptersScene(Demo demo, string name, int instanceIndex, string info)
        {
            this.demo = demo;
            this.name = name;
            this.instanceIndexName = " " + instanceIndex.ToString();
            this.info = info;

            // Create a new objects in the scene
            skyInstance1 = new Sky(demo, 1);
            quadInstance1 = new Quad(demo, 1);
            cursorInstance = new Cursor(demo);
            shotInstance = new Shot(demo);
            boxInstance = new Box1(demo, 1);
           // testObjectInstance = new TestObject(demo);
            wall1Instance = new Wall(demo, 1);
            wall1Instance2 = new Wall(demo, 2);
            wall1Instance3 = new Wall(demo, 3);
            defaultShapesInstance = new DefaultShapes(demo);
            testInstance = new Test(demo);
            userShapeInstance = new UserShapes(demo);

            camera2Instance1 = new Camera2(demo, 1);

            // Create a new controllers in the scene
            skyDraw1Instance1 = new SkyDraw1(demo, 1);
            cursorDraw1Instance = new CursorDraw1(demo);

            camera2Animation1Instance1 = new Camera2Animation1(demo, 1);
            camera2Draw1Instance1 = new Camera2Draw1(demo, 1);
        }

        public void Create()
        {
            string sceneInstanceIndexName = name + instanceIndexName;

            if (demo.Engine.Factory.PhysicsSceneManager.Find(sceneInstanceIndexName) != null) return;

            scene = demo.Engine.Factory.PhysicsSceneManager.Create(sceneInstanceIndexName);

            // Initialize maximum number of solver iterations for the scene
            scene.MaxIterationCount = 10;

            // Initialize time of simulation for the scene
            scene.TimeOfSimulation = 1.0f / 15.0f;

            Initialize();

            // Initialize objects in the scene
            skyInstance1.Initialize(scene);
            quadInstance1.Initialize(scene);
            cursorInstance.Initialize(scene);
            shotInstance.Initialize(scene);
            boxInstance.Initialize(scene); 
            wall1Instance.Initialize(scene);
            wall1Instance2.Initialize(scene);
            wall1Instance3.Initialize(scene);
            defaultShapesInstance.Initialize(scene);
            testInstance.Initialize(scene);
            userShapeInstance.Initialize(scene);

            camera2Instance1.Initialize(scene);

            // Initialize controllers in the scene
            skyDraw1Instance1.Initialize(scene);
            cursorDraw1Instance.Initialize(scene);

            camera2Animation1Instance1.Initialize(scene);
            camera2Draw1Instance1.Initialize(scene);

            // Create shapes shared for all physics objects in the scene
            // These shapes are used by all objects in the scene
            Demo.CreateSharedShapes(demo, scene);

            // Create shapes for objects in the scene
            Sky.CreateShapes(demo, scene);
            Quad.CreateShapes(demo, scene);
            Cursor.CreateShapes(demo, scene);
            Shot.CreateShapes(demo, scene);
            Box1.CreateShapes(demo, scene);
            Camera2.CreateShapes(demo, scene);
            Wall.CreateShapes(demo, scene);
            DefaultShapes.CreateShapes(demo, scene);
            UserShapes.CreateShapes(demo, scene);

            // Create physics objects for objects in the scene
            skyInstance1.Create(new Vector3(0.0f, 0.0f, 0.0f));
            quadInstance1.Create(new Vector3(0.0f, -40.0f, 20.0f), new Vector3(150.0f, 31.0f, 100.0f), Quaternion.Identity);
            cursorInstance.Create();
            shotInstance.Create();
            //boxInstance.Create(new Vector3(0.0f, 5.0f, -22.0f), new Vector3(0.2f, 0.2f, 0.2f), Quaternion.Identity, 5, new Vector3(0.3f, 0.3f, 0.3f), 0.5f);
            wall1Instance.Create(new Vector3(30f, 29f, 20.0f), new Vector3(80f, 30f, 10f), Quaternion.CreateFromAxisAngle(Vector3.UnitY, MathHelper.ToRadians(90f)), "Box", 30, new Vector3(30f, 0f, 20f), 500f, true);
            wall1Instance2.Create(new Vector3(-62f, 29f, -30.0f), new Vector3(80f, 30f, 10f), Quaternion.CreateFromAxisAngle(Vector3.UnitY, MathHelper.ToRadians(0f)), "Box", 30, new Vector3(30f, 0f, 20f), 500f, true);
            wall1Instance3.Create(new Vector3(-59.5f, 29f, 90.0f), new Vector3(80f, 30f, 10f), Quaternion.CreateFromAxisAngle(Vector3.UnitY, MathHelper.ToRadians(0f)), "Box", 30, new Vector3(30f, 0f, 20f), 500f, true);
            defaultShapesInstance.Create();
            camera2Instance1.Create(new Vector3(-30f, 0f, -22.0f), Quaternion.Identity, Quaternion.Identity, Quaternion.Identity, true);
            //userShapeInstance.Create();
            // testInstance.Create(new Vector3(0.0f, 5.0f, -22.0f), new Vector3(0.2f, 0.2f, 0.2f), Quaternion.Identity, 5, new Vector3(0.3f, 0.3f, 0.3f), 0.5f);

            // Set controllers for objects in the scene
            SetControllers();
        }

        public void Initialize()
        {
            scene.UserControllers.PostDrawMethods += demo.DrawInfo;

            scene.CreateLight(true);
            scene.Light.Type = PhysicsLightType.Directional;
            scene.Light.SetDirection(25f, 8f, 0.4f);
        }

        public void SetControllers()
        {
            skyDraw1Instance1.SetControllers();
            cursorDraw1Instance.SetControllers();

            camera2Animation1Instance1.SetControllers(false);
            camera2Draw1Instance1.SetControllers(false, false, false, false);
        }

        public void Refresh(double time)
        {
            camera2Animation1Instance1.RefreshControllers();
            camera2Draw1Instance1.RefreshControllers();

            demo.GraphicsDevice.Clear(ClearOptions.DepthBuffer, Color.Black, 1.0f, 0);

            scene.Simulate(time);
            scene.Draw(time);

            if (demo.EnableMenu)
            {
                demo.GraphicsDevice.Clear(ClearOptions.DepthBuffer, Color.Black, 1.0f, 0);
                demo.MenuScene.PhysicsScene.Draw(time);
            }
        }

        public void Remove()
        {
            string sceneInstanceIndexName = name + instanceIndexName;

            if (demo.Engine.Factory.PhysicsSceneManager.Find(sceneInstanceIndexName) != null)
                demo.Engine.Factory.PhysicsSceneManager.Remove(sceneInstanceIndexName);
        }

        public void UpdateResources()
        {
        }
    }
}
